Аналіз ДТП в Україні
Команда: Аліса Балакірська, Максим Кметь
import altair as alt
import pandas as pd
import geopandas as gpd
all_accidents_2020 = pd.read_excel('road_accidents_2020.xlsx', sheet_name = '2', header = 1)
#all_accidents.head()
roads_accidents_2020 = pd.read_excel('road_accidents_2020.xlsx', sheet_name = '9', header = 1)
roads_conditions_2020 = pd.read_excel('road_accidents_2020.xlsx', sheet_name = '15', header = 1)
streets_conditions_2020 = pd.read_excel('road_accidents_2020.xlsx', sheet_name = '16', header = 1)
accidents_by_day_2020 = pd.read_excel('road_accidents_2020.xlsx', sheet_name = '6', header = 1)
ukraine = gpd.read_file('ukraine.json')
cities = pd.read_csv('cities.csv')
ukraine.columns = ['GID_0', 'NAME_0', 'GID_1', 'region', 'VARNAME_1', 'NL_NAME_1',
'TYPE_1', 'ENGTYPE_1', 'CC_1', 'HASC_1', 'geometry']
cities_names = ukraine['region']
cities['city'] = ["Cherkasy", "Chernihiv", "Chernivtsi", "Dnipropetrovs'k", "Donets'k", "Ivano-Frankivs'k", "Kharkiv",
"Kherson", "Khmel'nyts'kyy", "Kyiv City", "Kirovohrad", "Luhans'k", "L'viv", "Mykolayiv", "Odesa",
"Poltava", "Rivne", "Sumy", "Ternopil'", "Vinnytsya", "Volyn", "Transcarpathia", "Zaporizhzhya", "Zhytomyr"]
parts = {"Cherkasy":"central", "Chernihiv":"north", "Chernivtsi":"west", "Dnipropetrovs'k":"east", "Donets'k":"east", "Ivano-Frankivs'k":"west", "Kharkiv":"east",
"Kherson":"south", "Khmel'nyts'kyy":"west", "Kyiv City":"north", "Kirovohrad":"central", "Luhans'k":"east", "L'viv":"west", "Mykolayiv":"south", "Odesa":"south",
"Poltava":"east", "Rivne":"west", "Sumy":"north", "Ternopil'":"west", "Vinnytsya":"central", "Volyn":"west", "Transcarpathia":"west", "Zaporizhzhya":"east", "Zhytomyr":"north"}
parts_df = pd.DataFrame.from_dict(parts, orient='index')
parts_df.columns = ['part']
parts_df = parts_df.reset_index()
d_2020 = {'region': cities['city'],'longitude': cities['longitude'], 'latitude': cities['latitude'], 'population': cities['population'],
'road_accidents': all_accidents_2020['all_road_accidents'], 'road_accidents_with_victims': all_accidents_2020['road_accidents_with_victims'],
'dead': all_accidents_2020['dead'], 'injured': all_accidents_2020['injured'], 'part': parts_df['part']}
data_2020 = pd.DataFrame(d_2020)
all_df = []
for year in ["2017", "2018", "2019", "2020"]:
cur_all_accidents = pd.read_excel('road_accidents_' + year +'.xlsx', sheet_name = '2', header = 1)
#cur_accidents_by_day_2020 = pd.read_excel('road_accidents_' + year +'.xlsx', sheet_name = '6', header = 1)
d_cur = {'year': int(year),'region': cities['city'],'longitude': cities['longitude'], 'latitude': cities['latitude'], 'population': cities['population'],
'road_accidents': cur_all_accidents['all_road_accidents'], 'road_accidents_with_victims': cur_all_accidents['road_accidents_with_victims'],
'dead': cur_all_accidents['dead'], 'injured': cur_all_accidents['injured'], 'part': parts_df['part']}
cur_df = pd.DataFrame(d_cur)
all_df.append(cur_df)
all_df = pd.concat(all_df)
all_df = all_df[~all_df["region"].isna()]
data_2020 = all_df[all_df["year"] == 2020]
all_df["region"] = all_df["region"].str.strip()
Візуалізувати кількість ДТП у різних регіонах в різні роки.
Ми вирішили візуалізувати кількість ДТП у різних регіонах на карті України, виділивши кількість кольором та цифрою. Також ми додали повзунок, яким можна змінити рік візуалізації (з 2017 по 2020). На візуалізації присутній тултіп з назвою регіону, а також на кожному регіоні позначена точно областного центру.
Така візуалізація дозволяє наглядно побачити які регіони є лідерами по кількості аварій, бо вони кольором відрізняються від усіх інших, а також побачити як змінювалася кількість аварій в регіонах по роках.
З мінусів цієї візуалізації - складно підібрати кольорову схему яка би описувала всі дані, а не виділяла лише аутлаєрів. Так відбувається через те що в більшості областей кількість аварій до 5000, а в Києві їх 39000, відповідно більшість областей виходять одного кольору. Так само в таку візуалізацію складно додати щоб колір регіонів змінювався коли змінюється рік.
input_slider = alt.binding_range(min=all_df.year.min(), max=all_df.year.max(), step=1, name='select year:')
select_year = alt.selection_single(name="year", fields = ['year'], bind=input_slider, init = {'year': 2020})
select_region = alt.selection_single(on = 'mouseover', nearest = False, fields = ['region'], empty = 'none')
ukraine.head()
| GID_0 | NAME_0 | GID_1 | region | VARNAME_1 | NL_NAME_1 | TYPE_1 | ENGTYPE_1 | CC_1 | HASC_1 | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | UKR | Ukraine | UKR.1_1 | Cherkasy | Cherkas'ka Oblast'|Cherkasskaya Oblast'|Cherkassy | None | Oblast' | Region | None | UA.CK | MULTIPOLYGON (((31.32614 48.74507, 31.31716 48... |
| 1 | UKR | Ukraine | UKR.2_1 | Chernihiv | Chernigov|Tschernigow | None | Oblast' | Region | None | UA.CH | MULTIPOLYGON (((33.09283 50.50966, 33.09261 50... |
| 2 | UKR | Ukraine | UKR.3_1 | Chernivtsi | Chernivets'ka Oblast'|Chernovitskaya Oblast'|C... | None | Oblast' | Region | None | UA.CV | MULTIPOLYGON (((24.93280 47.72794, 24.93301 47... |
| 3 | UKR | Ukraine | UKR.4_1 | Crimea | Crimée|Criméia|Krim|Krymskaya Respublika|Respu... | None | Autonomous Republic | Autonomous Republic | None | UA.KR | MULTIPOLYGON (((33.79291 44.39153, 33.79465 44... |
| 4 | UKR | Ukraine | UKR.5_1 | Dnipropetrovs'k | Dnipropetrovsk|Dniepropietrovsk|Dnjepropetrowsk | None | Oblast' | Region | None | UA.DP | MULTIPOLYGON (((33.93176 47.48407, 33.92332 47... |
base_back = alt.Chart(ukraine).project().mark_geoshape().encode(tooltip = alt.Tooltip('region:N'))
base = alt.Chart(ukraine).transform_lookup(
lookup = 'region',
from_ = alt.LookupData(data = all_df,
key = 'region',
fields=['road_accidents', 'region'])
).mark_geoshape(stroke = 'white', strokeWidth = 1
).encode(color = alt.Color('road_accidents:Q', scale = alt.Scale(scheme = 'reds')))
points = alt.Chart(cities).mark_point().encode(
longitude = alt.Longitude('longitude:Q'),
latitude = alt.Latitude('latitude:Q')
)
labels = alt.Chart(all_df).mark_text(
align = 'left',
baseline = 'middle',
dx = 15,
size = 12
).encode(
longitude = alt.Longitude('longitude:Q'),
latitude = alt.Latitude('latitude:Q'),
text = alt.Text('road_accidents:N')).transform_filter(select_year
)
selection = alt.Chart(ukraine).transform_lookup(
lookup = 'region',
from_ = alt.LookupData(data = all_df,
key = 'region',
fields=['road_accidents', 'region'])
).mark_geoshape(stroke='black', strokeWidth=2).encode(
color = alt.Color('road_accidents:Q', scale = alt.Scale(scheme = 'reds')),
opacity = alt.condition(select_region, alt.value(1), alt.value(1))
).transform_filter(select_region)
headline = alt.Chart(all_df).mark_text(
fontSize=15, align='left', lineBreak='\n', dy=20, dx=20).encode(
text=alt.value("Number of all road accidents in year"), x=alt.value(0), y=alt.value(0))
alt.layer(base_back, base, selection, points, labels, headline).configure_legend(orient = 'bottom-left').configure_view(strokeWidth = 0).properties(width = 800, height = 600).add_selection(select_year, select_region)
Візуалізувати співвідношення кількості аварій з жертвами до загальної кількості аварій по регіонах та по роках. На цій візуалізації показано співвідношення кількості аварій з жертвами до загальної кількості аварій по регіонах. Є повзунок по роках з 2017 по 2020. Регіони на візуалізації позначені бульбашками, розмір який залежить від кількості населення в регіоні. Це також дозволяє пропорційно порівняти як кількість населення впливає на кількість аварій. Всі регіони ми розділили на частини України, або побачити чи залежить безпечність аварій від частини України.
З візуалізації можемо побачити, що кількість аварій впринципі пропорційна до розміру населення в області. З цікавого, можна помітити що кількість жертв від аварій не завжди пропорційна до кількості аварій загалом. Наприклад, у 2020 році в Дніпропетровській області аварій було значно (в три рази) менше ніж в Київській, але жертв від аварій там було більше. З частин України лідерів немає лише з центральної частини, але це скоріш пов'язано з кількістю населення, а не з місцем розташування. Тож можемо зробити висновок що кількість аварій і жертв не залежить вид частини України.
Ми обрали саме такий спосіб візуалізації, бо він найкраще описує пропорційність чисел. Пропорцію ми могли так само описати використовуючи бар-чарти, але складно було би прив'язати дані до кількості населення в регіоні та до частини України.
input_slider = alt.binding_range(min=all_df.year.min(), max=all_df.year.max(), step=1, name='select year:')
select_year = alt.selection_single(name="year", fields = ['year'], bind=input_slider, init = {'year': 2020})
select_part = alt.selection_single(on = 'mouseover', fields = ['part'], nearest = False, empty = 'all')
alt.Chart(all_df).mark_point(filled = True).encode(
x = alt.X('road_accidents:Q', scale = alt.Scale(type = 'log',
base = 2,
domain = [all_df.road_accidents.min(),
all_df.road_accidents.max()]), title = "num road accidents"),
y = alt.Y('road_accidents_with_victims:Q', scale = alt.Scale(zero = True, domain = [all_df.road_accidents_with_victims.min(),
all_df.road_accidents_with_victims.max()]), title = "num road accidents with victims"),
tooltip = [
alt.Tooltip('region:N'),
alt.Tooltip('road_accidents:N'),
alt.Tooltip('road_accidents_with_victims:N')
],
color = alt.Color('part:N'),
size = alt.Size('population:Q'),
opacity = alt.condition(
select_part,
alt.value(0.8),
alt.value(0.3)
)
).add_selection(
select_part
).add_selection(
select_year
).transform_filter(select_year
).properties(width = 800, height = 500, background = '#F9F9F9', padding = 25)
Візуалізувати дороги на яких найчастіше трапляються аварії з жертвами(2020). (top15)
Для візуалізації доріг, на яких найчастіше трапляються аварії з жертвами (за 2020 рік) ми вибрали бар чарти. Ми посортували їх по кількості аварій та узяли топ-15 небезпечних доріг. Бар чарт складається з суми поранених та померлих людей під час аварії на цій дорозі.
Візуалізація дозволяє побачити найнебезпечніші дороги України - видно напрямок траси, номер, кількість жертв та померлих людей.
Альтернативою є візуалізація трас на карті України, але, на жаль, ми не змогли знайти потрібні дані для такої візуалізації.
roads_df = []
for ind, row in roads_accidents_2020.iterrows():
for c in ["dead", "injured"]:
r = {}
r["road"] = row["road"]
r["accident"] = c
r["num_people"] = row[c]
roads_df.append(r)
roads_df = pd.DataFrame(roads_df)
alt.Chart(roads_df.groupby(by="road").sum().sort_values(
by="num_people", ascending=False).merge(roads_df[["road","accident"]], how="inner", on= "road").head(30)).mark_bar().encode(
x = alt.X('num_people:Q', title="number of people"),
y = alt.Y('road:N', sort='-x'),
color = alt.Color('accident:N'),
tooltip = [alt.Tooltip('accident:N'), alt.Tooltip('num_people:Q')],
).properties(width = 700, height = 600)
Візуалізувати в яких містах найчастіше люди стають жертвами аварій через незадовільний стан доріг(2020).
Для візуалізації міст, в яких найчастіше люди стають жертвами аварій через незадовільний стан доріг (за 2020 рік) ми також вибрали бар чарти. Бар чарт складається з суми поранених та померлих людей під час аварій.
Візуалізація дозволяє побачити області, в яких найгірші дороги України.
Альтернативою є візуалізація карти України з бар-чартом на кожній області, який складався б з кількості жертв та померлих людей в обласному центрі цієї області.
roads_conditions_df = []
for ind, row in roads_conditions_2020.iterrows():
for c in ["dead", "injured"]:
r = {}
r["region"] = row["region"]
r["accident"] = c
r["number"] = row[c]
roads_conditions_df.append(r)
roads_conditions_df = pd.DataFrame(roads_conditions_df)
alt.Chart(roads_conditions_df).mark_bar().encode(
x = alt.X('number:Q', aggregate = 'sum', sort=alt.Sort(field="number"), title="number of people"),
y = alt.Y('region:N', sort='-x'),
color = alt.Color('accident:N'),
tooltip = [alt.Tooltip('accident'), alt.Tooltip('number')],
).properties(width = 700, height = 500)
Візуалізувати в яких містах найчастіше люди стають жертвами аварій через незадовільний стан вулиць (2020).
Для візуалізації міст, в яких найчастіше люди стають жертвами аварій через незадовільний стан вулиць (за 2020 рік) ми так само вибрали бар чарти. Бар чарт складається з суми поранених та померлих людей під час аварій.
Візуалізація дозволяє побачити області, в яких найбільше аварій через незадовільний стан вулиць України.
Альтернативою є візуалізація карти України з бар-чартом на кожній області, який складався б з кількості жертв та померлих людей в обласному центрі цієї області.
streets_conditions_df = []
for ind, row in streets_conditions_2020.iterrows():
for c in ["dead", "injured"]:
r = {}
r["region"] = row["region"]
r["accident"] = c
r["number"] = row[c]
streets_conditions_df.append(r)
streets_conditions_df = pd.DataFrame(streets_conditions_df)
alt.Chart(streets_conditions_df).mark_bar().encode(
x = alt.X('number:Q', aggregate = 'sum', sort=alt.Sort(field="number"), title="number of people"),
y = alt.Y('region:N', sort='-x'),
color = alt.Color('accident:N'),
tooltip = [alt.Tooltip('accident'), alt.Tooltip('number')],
).properties(width = 700, height = 500)